package br.com.sebrae.pr.sgp.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import org.apache.commons.lang3.StringUtils;

import br.com.sebrae.pr.sgp.dao.ProcessoDAO;
import br.com.sebrae.pr.sgp.dao.base.BaseDao;
import br.com.sebrae.pr.sgp.entities.Cliente;
import br.com.sebrae.pr.sgp.entities.Processo;
import br.com.sebrae.pr.sgp.util.persistence.IConverter;
import br.com.sebrae.pr.sgp.util.persistence.ItemResultset;
import br.com.sebrae.pr.sgp.util.persistence.params.InParam;
import br.com.sebrae.pr.sgp.util.persistence.params.ParamType;

import com.google.common.base.Preconditions;

@Stateless
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class ProcessoDaoImpl extends BaseDao implements ProcessoDAO {

	@Override
	public Processo pesquisarPorId(final long id) {
		final Processo filtro = new Processo();
		filtro.setId(id);
		final List<Processo> ret = pesquisar(filtro);
		if (ret.iterator().hasNext()) {
			return ret.iterator().next();
		}
		return null;
	}

	@Override
	public Processo pesquisarPorNomeClienteLogin(final String nmeCliente) {
		final Processo filtro = new Processo();
		// filtro.setCliente(nmeCliente);
		final List<Processo> ret = pesquisar(filtro);
		if (ret.iterator().hasNext()) {
			return ret.iterator().next();
		}
		return null;
	}

	@Override
	public List<Processo> efetuarPesquisa(final Processo processo) {
		return pesquisar(processo, true);
	}

	/**
	 * Pesquisa os usuários utilizando os campos do {@link Processo} parâmetro como filtros. Não utiliza like mas =
	 * 
	 * @see ProcessoDaoImpl#pesquisar(Processo, boolean)
	 * 
	 * @param filtro
	 * @return
	 */
	private List<Processo> pesquisar(final Processo filtro) {
		return pesquisar(filtro, false);
	}

	/**
	 * Pesquisa os usuários utilizando os campos do {@link Processo} parâmetro como filtros. Utiliza LIKE se o parametro paraPesquisa = true
	 * 
	 * @param filtro
	 * @param paraPesquisa
	 * @return
	 */
	private List<Processo> pesquisar(final Processo filtro, final boolean paraPesquisa) {
		final List<InParam> params = new ArrayList<InParam>();

		final StringBuffer sql = new StringBuffer();
		sql.append("SELECT p.id,p.codigo,c.nome,p.descricao,p.status,c.tel_celular,c.tel_comercial \n");
		sql.append("  FROM processo p inner join cliente c on p.id_cliente = c.id \n");
		sql.append(" WHERE p.ativo = true \n");
		if (filtro != null) {
			if (paraPesquisa) {
				 if (filtro.getCliente() != null && StringUtils.isNotBlank(filtro.getCliente().getNome())) {
					 sql.append("   AND UPPER(c.nome) LIKE(?) \n");
					 params.add(new InParam(params.size() + 1, "%" + filtro.getCliente().getNome().toUpperCase() + "%", ParamType.VARCHAR));
				 }
				 if (filtro.getCodigo() > 0) {
					 sql.append("   AND p.codigo = ? \n");
					 params.add(new InParam(params.size() + 1, filtro.getCodigo(), ParamType.NUMERIC));
				 }
				 if (filtro.getStatus() > 0) {
					 sql.append("   AND p.status = ? \n");
					 params.add(new InParam(params.size() + 1, filtro.getStatus(), ParamType.NUMERIC));
				 }
			}
		}
		return executarQuery(sql, params, new IConverter<Processo>() {

			@Override
			public Processo convert(final ItemResultset reg) {
				final Processo processo = new Processo();
				processo.setId(reg.getLong("id"));
				processo.setCodigo(reg.getLong("codigo"));
				processo.setDescricao(reg.getString("descricao"));
				processo.setStatus(reg.getInt("status"));
				final Cliente cliente = new Cliente();
				cliente.setNome(reg.getString("nome"));
				cliente.setTelCelular(reg.getString("tel_celular"));
				cliente.setTelComercial(reg.getString("tel_comercial"));
				processo.setCliente(cliente);
				// ret.setNomeUsuario(reg.getString("nome_usuario"));
				return processo;
			}
		});
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public Processo salvarOuAtualizar(final Processo processo) {
		Preconditions.checkNotNull(processo, "Processo é obrigatório e deve ser informado!");
//		Preconditions.checkNotNull(processo.getCliente(), "Cliente é obrigatório e deve ser informado");
		Preconditions.checkNotNull(processo.getDescricao(), "Descrição é obrigatório e deve ser informado");
		final List<InParam> params = new ArrayList<InParam>();
		if (inclusao(processo)) {
			// throw new IllegalArgumentException("Inclusão de usuários não é contemplada no sistema!");
			final StringBuffer sql = new StringBuffer();
			sql.append("INSERT INTO processo ");
			sql.append("	(dt_inclusao,id_usuario_inclusao,ativo,id_cliente, status, descricao)");
			sql.append(" VALUES (?,?,?,?,?,?);");

			params.add(new InParam(params.size() + 1, new Date(), ParamType.DATE));
			params.add(new InParam(params.size() + 1, 1, ParamType.NUMERIC));
			params.add(new InParam(params.size() + 1, 1, ParamType.BOOLEAN));
			params.add(new InParam(params.size() + 1, processo.getCliente().getId(), ParamType.NUMERIC));
			params.add(new InParam(params.size() + 1, processo.getStatus(), ParamType.NUMERIC));
			params.add(new InParam(params.size() + 1, processo.getDescricao(), ParamType.VARCHAR));

			executarUpdate(sql, params);
		} else {
			final StringBuffer sql = new StringBuffer();
			sql.append("UPDATE master.tb1083_vc_user \n");
			sql.append("   SET a1083_usr_svn = ?, \n");
			sql.append("       a1083_email = ?, \n");
			sql.append("       a1083_passwd_md5 = ?, \n");
			sql.append("       a1083_ind_admin = ?, \n");
			sql.append("       a1083_ind_desenv = ?, \n");
			sql.append("       a1083_ind_integrador = ?, \n");
			sql.append("       a1083_ind_aprovador = ?, \n");
			sql.append("       a1083_ind_testador = ?, \n");
			sql.append("       a1083_ind_dba = ?, \n");
			sql.append("       a1083_ind_po = ?, \n");
			sql.append("       a1083_dt_atz = ?, \n");
			sql.append("       a0015_cod_agente_atz = ? \n");
			sql.append(" WHERE a0015_cod_agente = ? \n");

			// params.add(new InParam(params.size() + 1, usuario.getNmeUsuarioSvn(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getDesEmail(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getDesSenha(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getAdmin(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getDesenvolvedor(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getIntegrador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getAprovador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getTestador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getDba(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getPo(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, new Date(), ParamType.TIMESTAMP));
			// params.add(new InParam(params.size() + 1, usuario.getUsuarioLogado().getId(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getId(), ParamType.NUMERIC));

			executarUpdate(sql, params);

		}
		return processo;
	}
}
